package com.swan.web.auto;

import com.swan.web.aop.HttpLogAspect;
import com.swan.web.aop.LogbackLogIdInjectInterceptor;
import com.swan.web.auto.config.SpringWebConfig;
import com.swan.web.auto.config.WebConfig;
import com.swan.web.exception.DefaultUnknownExceptionHandler;
import com.swan.web.exception.GlobalExceptionHandler;
import com.swan.web.exception.IExceptionHandler;
import com.swan.web.exception.IUnknownExceptionHandler;
import org.aopalliance.aop.Advice;
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

import java.util.List;

/**
 * @author zongf
 * @date 2025-02-08
 **/
@Configuration(proxyBeanMethods = false)
@Import(WebConfig.class)
public class WebAutoConfig {

    /** logback 配置*/
    @Bean
    @ConditionalOnProperty(name = "swan.web.logback.injectLogId")
    public LogbackLogIdInjectInterceptor logbackLogIdInjectInterceptor(WebConfig webConfig) {
        return new LogbackLogIdInjectInterceptor(webConfig);
    }

    /** 全局异常处理 */
    @Bean
    @ConditionalOnProperty(name = "swan.web.exception.enable", matchIfMissing = true)
    public GlobalExceptionHandler globalExceptionHandler(List<IExceptionHandler> exceptionHandlers) {
        return new GlobalExceptionHandler(exceptionHandlers);
    }

    /** 默认未知异常处理 */
    @Bean
    @ConditionalOnMissingBean
    public IUnknownExceptionHandler unknownExceptionHandler(WebConfig webConfig) {
        return new DefaultUnknownExceptionHandler(webConfig);
    }

    @Bean
    public MvcConfig mvcConfig(){
        return new MvcConfig();
    }

    @Value("${server.servlet.context-path:}")
    private String serverContextPath;

    @Bean
    @ConditionalOnProperty(name = "swan.web.httpLog.enable", matchIfMissing = true)
    public DefaultPointcutAdvisor request(WebConfig webConfig) {

        String expression = String.format("execution(* %s..*Controller.*(..))", webConfig.getHttpLog().getControllerPackage());

        AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
        pointcut.setExpression(expression);

        Advice advice = new HttpLogAspect(webConfig, serverContextPath);
        return new DefaultPointcutAdvisor(pointcut, advice);
    }

    @Bean
    public SpringWebConfig springWebConfig(){
        return new SpringWebConfig();
    }

}
